#include "commandhandler.h"
#include <QStringList>
#include <QRegularExpression>
#include <QApplication>

CommandHandler::CommandHandler(VirtualDisk* vd, QObject *parent)
    : QObject(parent), vdisk(vd) {
    current_dir_block = 0;
    current_path = "\\";
    pathHistory.push_back(0);
}

void CommandHandler::processCommand(QString command) {
    command = command.trimmed();
    if (command.isEmpty()) return;

    QString output;

    static const QRegularExpression mdRegex(
        "^md\\s+([a-zA-Z0-9_]{1,8})$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression cdRegex(
        "^cd\\s*([\\\\.]{1,2}|[a-zA-Z0-9_]{1,8})?$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression rdRegex(
        "^rd\\s+([a-zA-Z0-9_]{1,8})$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression mkRegex(
        "^mk\\s+([a-zA-Z0-9_\\.]{1,8})\\s+(\\d+)$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression delRegex(
        "^del\\s+([a-zA-Z0-9_\\.]{1,8})$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression dirRegex(
        "^dir$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression infoRegex(
        "^info$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression clearRegex(
        "^clear$",
        QRegularExpression::CaseInsensitiveOption
        );
    static const QRegularExpression exitRegex(
        "^exit$",
        QRegularExpression::CaseInsensitiveOption
        );

    // 匹配MD命令
    QRegularExpressionMatch match = mdRegex.match(command);
    if (match.hasMatch()) {
        QString dirName = match.captured(1);
        if (!vdisk->createDir(current_dir_block, dirName)) {
            output = "Error: 目录已存在或空间不足";
        }
    }
    // 匹配CD命令
    else if ((match = cdRegex.match(command)).hasMatch()) {
        QString arg = match.captured(1);
        if (arg.isEmpty() || arg == "\\") {
            current_dir_block = 0;
            current_path = "\\";
            pathHistory.clear();
            pathHistory.push_back(0);
        } else if (arg == "..") {
            if (pathHistory.size() > 1) {
                pathHistory.pop_back();
                current_dir_block = pathHistory.last();
                current_path = current_path.left(current_path.lastIndexOf('\\', current_path.length() - 2) + 1);
            }
        } else {
            FCB dirFCB = vdisk->findFCB(current_dir_block, arg);
            if (dirFCB.type == 2) {
                current_dir_block = dirFCB.first_block;
                pathHistory.push_back(current_dir_block);
                current_path += arg + "\\";
            } else {
                output = "Error: 目录不存在";
            }
        }
        output = current_path;
    }

    else if ((match = rdRegex.match(command)).hasMatch()) {
        QString dirName = match.captured(1);
        if (!vdisk->deleteDir(current_dir_block, dirName)) {
            output = "Error: 目录非空或不存在";
        }
    }

    else if ((match = mkRegex.match(command)).hasMatch()) {
        QString fileName = match.captured(1);
        int size = match.captured(2).toInt();
        if (!vdisk->createFile(current_dir_block, fileName, size)) {
            output = "Error: 文件已存在或空间不足";
        }
    }

    else if ((match = delRegex.match(command)).hasMatch()) {
        QString fileName = match.captured(1);
        if (!vdisk->deleteFile(current_dir_block, fileName)) {
            output = "Error: 文件不存在";
        }
    }

    else if (dirRegex.match(command).hasMatch()) {
        QVector<FCB> fcbs = vdisk->listFCBs(current_dir_block);
        output = QString("Directory of %1\n\n").arg(current_path);
        for (const FCB& fcb : fcbs) {
            QString dt = QString(fcb.datetime);
            QString date = dt.mid(0,4) + "-" + dt.mid(4,2) + "-" + dt.mid(6,2);
            QString time = dt.mid(8,2) + ":" + dt.mid(10,2) + ":" + dt.mid(12,2);
            if (fcb.type == 2) {
                output += QString("%1  <DIR>          %2  %3\n")
                .arg(QString(fcb.name).leftJustified(15))
                    .arg(date).arg(time);
            } else {
                output += QString("%1  %2  %3  %4\n")
                .arg(QString(fcb.name).leftJustified(15))
                    .arg(QString::number(fcb.size).rightJustified(10))
                    .arg(date).arg(time);
            }
        }
    }

    else if (infoRegex.match(command).hasMatch()) {
        output = vdisk->getInfo();
    }

    else if (clearRegex.match(command).hasMatch()) {
        emit clearRequested();
        return;
    }

    else if (exitRegex.match(command).hasMatch()) {
        vdisk->save();
        output = "程序退出，虚拟磁盘已保存";
        emit outputGenerated(output);
        QApplication::quit();
        return;
    }

    else {
        output = "Error: 命令格式错误！支持的命令：\n"
                 "MD <目录名>  创建目录（1-8位字母/数字/下划线）\n"
                 "CD <目录名|..|\\>  切换目录\n"
                 "RD <目录名>  删除空目录\n"
                 "MK <文件名> <大小>  创建文件（大小为非负整数）\n"
                 "DEL <文件名>  删除文件\n"
                 "DIR  列出目录\n"
                 "INFO  查看磁盘信息\n"
                 "CLEAR  清空屏幕\n"
                 "EXIT  退出程序";
    }

    if (!output.isEmpty()) {
        emit outputGenerated(output);
    }
}
